import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;





public class PuertoRico extends Factory {
	private LinkedList<Jugador> jugadores;
	private Iterator<Jugador> jugadoresIt;
	private Map<String,Roles> rol;
	private Roles roles;
	private boolean finRonda=false;
	private Gobernador gobernador;
	private Jugador jugadorGobernador;
	private Jugador jugadorRol;
	private Jugador jugadorTurno;
	private boolean finTurno=false;
	private boolean privilegio;
	private Factory fact = new Factory();
	private Recursos recursos = Recursos.getInstancia();
	
	
	public PuertoRico(){
		jugadores = new LinkedList<Jugador>();
		try {
			fact.creaRoles();
			} catch (Exception e) {
			
			}
		rol = new HashMap<String,Roles>();
		fact.crearJugador(jugadores); 
		
	}
	
	public int establecerJugadores(){
		/*Este metodo esta puesto por la sencilla razon de que 
		tenemos que dejar el programa preparado para que, en un futuro hipotetico,
		se pueda implementar una rutina que permita la seleccion de 3, 4 o 5 jugadores*/
		return 4;
	}
	
	public void addJugador(String nombre){//Esto o lo hace la fabrica o PuertoRico, pero no los dos a la vez
		Jugador jug = new Jugador(nombre);
		jugadores.add(jug);
	}
	
	public void Jugar(){
		Collection<Jugador> jugadoresG = new LinkedList<Jugador>();
		Collection<Jugador> jugadoresR = new LinkedList<Jugador>();
		Collection<Jugador> jugadoresT = new LinkedList<Jugador>();
		jugadoresG.addAll(jugadores);
		jugadoresR.addAll(jugadores);
		jugadoresT.addAll(jugadores);
		jugadorGobernador = generarGobernador();
		jugadorRol = jugadorGobernador;
		jugadorTurno = jugadorGobernador;
		while (!(finRonda||condicionDeVictoria())){
			Roles rolActual = elegirRol(rol);
			privilegio = false;
			while (!(finTurno||condicionDeVictoria())){
				rolActual.accion(jugadorTurno, privilegio);
				privilegio = true;
				jugadorTurno = siguienteJugador(jugadoresT);
				if (jugadorTurno==jugadorRol){
					finTurno=true;
				}
				jugadorRol = siguienteJugador(jugadoresR);
			}
			if((jugadorRol==jugadorGobernador)&&(rol.size()==2)){														
				finRonda=true; 										
				roles.ponerDoblon(rol); 
                jugadorGobernador = siguienteJugador(jugadoresG);
                gobernador.setJugador(jugadorGobernador);
			}
		}
		Jugador G = ganador(jugadores);
		System.out.println ("Enhorabuena "+G.getnombre()+", has ganado." );
		}
	
	private Jugador siguienteJugador(Collection<Jugador> jug) {
		if (!jugadoresIt.hasNext()) {
			jugadoresIt = jug.iterator();
		}
		return jugadoresIt.next();
	}
	
	private Roles elegirRol(Map<String, Roles> rol){//Completa
		Set<Map.Entry<String, Roles>> roles = rol.entrySet();
		Iterator<Map.Entry<String, Roles>> rolesIt = roles.iterator();
		while (rolesIt.hasNext()){
			Map.Entry<String, Roles> entry = (Map.Entry<String, Roles>) rolesIt.next();
			System.out.println(entry.getKey()+" "+entry.getValue());
		}
		try{
			System.out.println("Selecciona rol: ");
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String key = br.readLine();
			return rol.remove(key);
			
		} catch(Exception e){
			
		}
		return null;
	}
	
		
	private boolean condicionDeVictoria(){//Completa
		boolean cond = false;
		if (recursos.getColonos()==0){
			cond = true;
			}
			
		if (recursos.getPV() == 0){
			cond = true;
			}
			
		if (jugadorRol.sizeOfEdificios()==13){
			cond = true;
		}
		
		return cond;
		
	}
        
	private Jugador generarGobernador(){//Completa
            Gobernador gobernador = Gobernador.getInstance();
			Random random = new Random();
            int gob = (Math.abs(random.nextInt()) % establecerJugadores()) + 1;
            Jugador j = jugadores.get(gob);
            gobernador.setJugador(j);
            return j;
        }

	
	
	private	int cuentaPv (Jugador jugador){
		Edificios ed;
		Iterator<Edificios> edificiosIt = jugador.getEdificios().iterator();
		int res=jugador.getPV();
		while (edificiosIt.hasNext()){
			ed = edificiosIt.next();
			res = res + ed.getPv(); 
		}
		
		return res;
	}

	private Jugador ganador (LinkedList<Jugador> jugadores){
		Jugador winner = null;
		int tamano=jugadores.size(); 
		int max= Integer.MIN_VALUE; 
		for (int i = 0; i < tamano; i++) {
			Jugador jug = (Jugador)jugadores.get(i);
			if (max<cuentaPv(jug)){
				max=cuentaPv(jug);
				winner=(Jugador)jugadores.get(i);
			}
		}
		return winner;
	}
}
